import React, { useState, useRef, useEffect } from 'react';
import {
    View,
    StyleSheet,
    Animated,
    PanResponder,
    Dimensions,
    Text,
    I18nManager,
    StyleProp,
    ViewStyle,
    PanResponderGestureState,
    GestureResponderEvent,
} from 'react-native';

import Icon from 'react-native-vector-icons/Ionicons';
import { px2dp } from '~/utils/px2dp';
const { height: SCREEN_HEIGHT } = Dimensions.get('window');

type VolumeControlPosition = 'left' | 'right';

interface VolumeControlProps {
    initialVolume?: number;
    barHeight?: number;
    barWidth?: number;
    barColor?: string;
    backgroundColor?: string;
    iconSize?: number;
    textSize?: number;
    autoHideTimeout?: number;
    sensitivity?: number;
    showPercentage?: boolean;
    showIcon?: boolean;
    position?: VolumeControlPosition;
    style?: StyleProp<ViewStyle>;
    onVolumeChange?: (volume: number) => void;
    onVolumeEnd?: (volume: number) => void; // 新增滑动结束回调
    renderIcon?: (volume: number) => React.ReactNode;
    renderText?: (volume: number) => React.ReactNode;
}

const VolumeControl: React.FC<VolumeControlProps> = ({
    initialVolume = 50,
    barHeight = SCREEN_HEIGHT * 0.5,
    barWidth = 30,
    barColor = '#007AFF',
    backgroundColor = 'rgba(0, 0, 0, 0.2)',
    iconSize = 24,
    textSize = 14,
    autoHideTimeout = 3000,
    sensitivity = 0.5,
    showPercentage = true,
    showIcon = true,
    position = 'right',
    style,
    onVolumeChange,
    onVolumeEnd, // 新增prop
    renderIcon,
    renderText,
}) => {
    const [displayVolume, setDisplayVolume] = useState<number>(Math.min(100, Math.max(0, initialVolume))); // 用于显示
    const actualVolume = useRef<number>(Math.min(100, Math.max(0, initialVolume))); // 存储实际值
    const [showControl, setShowControl] = useState<boolean>(false);
    const fadeAnim = useRef<Animated.Value>(new Animated.Value(0)).current;
    const controlTimeout = useRef<NodeJS.Timeout | null>(null);
    const isSliding = useRef<boolean>(false);

    const resetTimer = (): void => {
        if (controlTimeout.current) {
            clearTimeout(controlTimeout.current);
        }
        controlTimeout.current = setTimeout(hideVolumeControl, autoHideTimeout);
    };

    const showVolumeControl = (): void => {
        setShowControl(true);
        Animated.timing(fadeAnim, {
            toValue: 1,
            duration: 200,
            useNativeDriver: true,
        }).start();
        resetTimer();
    };

    const hideVolumeControl = (): void => {
        Animated.timing(fadeAnim, {
            toValue: 0,
            duration: 300,
            useNativeDriver: true,
        }).start(() => setShowControl(false));
    };

    const adjustVolume = (newVolume: number): void => {
        const adjustedVolume = Math.max(0, Math.min(100, newVolume));
        actualVolume.current = adjustedVolume; // 更新ref值
        setDisplayVolume(adjustedVolume); // 更新显示值
        if (onVolumeChange) {
            onVolumeChange(adjustedVolume);
        }
        showControl ? resetTimer() : showVolumeControl();
    };

    const handleVolumeEnd = (): void => {
        if (onVolumeEnd && isSliding.current) {
            onVolumeEnd(actualVolume.current);
        }
        isSliding.current = false;
    };

    const panResponder = useRef(
        PanResponder.create({
            onStartShouldSetPanResponder: (): boolean => true,
            onMoveShouldSetPanResponder: (): boolean => true,
            onPanResponderGrant: (): void => {
                isSliding.current = true;
                showVolumeControl();
            },
            onPanResponderMove: (_: GestureResponderEvent, { dy }: PanResponderGestureState): void => {
                if (isSliding.current) {
                    adjustVolume(actualVolume.current - dy * sensitivity); // 使用ref当前值计算
                }
            },
            onPanResponderRelease: (): void => {
                handleVolumeEnd();
                resetTimer();
            },
            onPanResponderTerminate: (): void => {
                handleVolumeEnd();
                resetTimer();
            },
        }),
    ).current;
    useEffect(() => {
        return (): void => {
            if (controlTimeout.current) {
                clearTimeout(controlTimeout.current);
            }
        };
    }, []);

    const getVolumeIcon = () => {
        if (displayVolume == 0) return <Icon name={'volume-mute'} size={px2dp(50)} color={'#a4a4a4'} />;
        if (displayVolume < 50) return <Icon name={'volume-medium'} size={px2dp(50)} color={'#a4a4a4'} />;
        if (displayVolume < 70) return <Icon name={'volume-high'} size={px2dp(50)} color={'#a4a4a4'} />;
        return <Icon name={'volume-high'} size={px2dp(50)} color={'#a4a4a4'} />;
    };
    const fillHeight: number = (displayVolume / 100) * barHeight;

    const verticalPosition = (SCREEN_HEIGHT - barHeight) / 3;

    const positionStyle: ViewStyle = {
        [position]: 20,
        top: verticalPosition,
    };

    return (
        <View style={[styles.container, style]} {...panResponder.panHandlers}>
            {showControl && (
                <Animated.View
                    style={[
                        styles.volumeContainer,
                        positionStyle,
                        {
                            opacity: fadeAnim,
                            height: barHeight,
                        },
                    ]}>
                    <View style={[styles.volumeBar, { width: barWidth }]}>
                        <View style={[styles.volumeBarBackground, { backgroundColor }]} />
                        <View
                            style={[
                                styles.volumeBarFill,
                                {
                                    height: fillHeight,
                                    backgroundColor: barColor,
                                    [I18nManager.isRTL ? 'left' : 'right']: 0,
                                },
                            ]}
                        />
                        {showIcon &&
                            (renderIcon ? (
                                renderIcon(actualVolume.current)
                            ) : (
                                <View style={styles.icon}>{getVolumeIcon()}</View>
                            ))}
                    </View>
                </Animated.View>
            )}
        </View>
    );
};

const styles = StyleSheet.create({
    container: {
        ...StyleSheet.absoluteFillObject,
        // zIndex: 1,
    },
    volumeContainer: {
        position: 'absolute',
        alignItems: 'center',
        justifyContent: 'flex-end',
    },
    volumeBar: {
        height: '100%',
        borderRadius: px2dp(40),
        overflow: 'hidden',
        justifyContent: 'flex-end',
        marginBottom: 10,
    },
    volumeBarBackground: {
        ...StyleSheet.absoluteFillObject,
    },
    volumeBarFill: {
        width: '100%',
        position: 'absolute',
        bottom: 0,
    },
    volumeIcon: {
        marginBottom: 5,
    },
    volumeText: {
        color: '#000',
        fontWeight: 'bold',
    },
    icon: {
        alignSelf: 'center',
        marginBottom: px2dp(40),
    },
});

export default VolumeControl;
